import { ETaskState } from "GameLoop/DecisionMaking/TaskDeclare/type";
import { TeamUpgrader } from "GameLoop/WorldState/EntityManager/Entitys";
import { ATeamEntity } from "GameLoop/WorldState/EntityManager/Entitys/team";
import { BodyEfficiency } from "utils/creep/bodyEfficiency";
import { WarStrategy } from "utils/war/WarStrategy";
import { DefendTaskCheck } from "./TeamCheck/DefendTaskCheck";
import { BodyUtils } from "utils/creep/bodyutils";
import { getRoleConfig } from "utils/constants/bodyconstant";
 
export class TeamTaskChecker
{
    public static notify:Notify
    public static check(room:Room,task:ITaskDeclare["team"])
    {
        switch(task.data.type)
        {
            case "upgrade":
                return this.checkUpgrade(room,task as any)
            case "defend":
                return this.checkDefend(room,task as any)
            case "defendram":
                return this.checkDefendRam(room,task as any)
            
        }
        // return ETaskState.Running;
    }
    private static checkUpgradeNew(room:Room,task:ITask<ITeamTaskData<"upgrade">>):ETaskState
    {
        const teams = task.data.teams["TeamUpgrader"];
        if(!teams)
        {
            return ETaskState.Running;
        }

        const targetroom = Game.rooms[task.data.room];

        const controllerentity =targetroom.controller;
        if(!controllerentity)
        {
            return  ETaskState.Running;
        }
        
        for(const e of teams)
        {
            
            const core = targetroom.getEntity("CoreEntity");
            const stores = core.Container?[core.Container]:[];
         
            const level = controllerentity.level;
            if(level<8)
            {
                if(stores.length>0  )
                {
                    if(!targetroom.canExecute(50+100*(level-1)))
                    {
                        // 没400T检测一次爬的数量
                        continue;
                    }
                   
                    const team = room.getEntityByID<TeamUpgrader>(e);
                    const upgraderRequird = team.getNodeMemory().required.find(e=>e[0].Role == "upgrader") as [IBodyConfig, number];
                    const max = team.maxWorker();
                    const creeps = team.getNodeMemory().creeps["upgrader"];
                    const works = _.sum(creeps,e=>Game.creeps[e]&& Game.creeps[e].getActiveBodyparts(WORK));
                    targetroom.getNodeMemory().stats.upgradeWork =  works ;
                    
                    upgraderRequird[0].body=getRoleConfig("upgrader",room.controller?.level as number).body ;// 重新配置body的体型
                  

                    if(team.getWorkProgress()*0.5> controllerentity.leftProgress()*1.1)
                    {
                        // 剩余的升级Work时间内已经可以升级了。
                        upgraderRequird[1]=BodyEfficiency.getCreepCount("upgrader",room.controller?.level as number,WORK,10);;
                        team.log("info",`更新升级工数量`,`足够升到下一级`)
                        continue;
                    }
                    if(!core.Storage )
                    {
                        // 当当前所有的upgrader的效率能够使控制器升级时。则不再新增孵化
                        if(stores[0].store.getUsedCapacity(RESOURCE_ENERGY)> stores[0].store.getCapacity()*0.7)
                        {
                            // 当控制器的能量还很充足时。增加升级工的数量
                            
                            if(max> upgraderRequird[1])
                            {
                                if(room.getEntity("SpawnEntity").getTasksByOwner(e))
                                {
                                    // 已经有孵化任务了不能再加了
                                    continue;
                                }
                                upgraderRequird[1]++;
                                team.log("info",`更新升级工数量`,`只有container`,'提升数量',upgraderRequird[1],team.getNodeMemory().required)
                            }
                        }
                        else if(stores[0].store.getUsedCapacity(RESOURCE_ENERGY)==0) 
                        {
                            if(  upgraderRequird[1]>1)
                            {
                                upgraderRequird[1]--;
                                team.log("info",`更新升级工数量`,`只有container`,'能量耗尽',upgraderRequird[1])
                            }
                        }
                    }
                    else 
                    {
                        if(core.resourceCount(RESOURCE_ENERGY)>120000)
                        {
                            if(max> upgraderRequird[1])
                            {
                                if(room.getEntity("SpawnEntity").getTasksByOwner(e))
                                {
                                    // 已经有孵化任务了不能再加了
                                    continue;
                                }
                                upgraderRequird[1]++;
                                team.log("info",`更新升级工数量`,`storage`,'+1',`[${max}]->${upgraderRequird[1]}`)
                            }
                        }
                        else 
                        {
                            upgraderRequird[1]=1;
                            team.log("info",`更新升级工数量`,`storage`,'设置为1',`[${max}]->${upgraderRequird[1]}`)
                        }
                        
                    }
                }
                else
                {
                    // 没有store则。此任务销毁
                    if(
                        (core.Storage&& core.Storage.pos.distance(controllerentity.pos)<=4)
                        ||
                        (core.Terminal&& core.Terminal.pos.distance(controllerentity.pos)<=4)
                    )
                    {
                        // 存在资源仓库
                        return ETaskState.Running;
                    }
                    return ETaskState.Complete;
                }
            }
            else
            {
                // 到8了
                const team = room.getEntityByID<TeamUpgrader>(e);
                const upgraderRequird = team.getNodeMemory().required.find(e=>e[0].Role == "upgrader") as [IBodyConfig, number];
                upgraderRequird[1]=1;
                // return ETaskState.Complete; 这里应该要任务完成
            }
            

        }
        return ETaskState.Running;
    }
    private static checkUpgrade (room:Room,task:ITask<ITeamTaskData<"upgrade">>):ETaskState
    {
        const targetroom = Game.rooms[task.data.room];

 
        const coreEntity =targetroom.getEntity("CoreEntity");
        
        if(!task.data.arg.layoutType)
        {
            if(coreEntity.Container && coreEntity.Container.pos.distance(targetroom.controller!.pos)<=3)
            {
                task.data.arg.layoutType = 1;
            }
            else if ( coreEntity.ManagerPosition.distance(targetroom.controller!.pos)<=3)
            {
                task.data.arg.layoutType = 1;
            }
            else 
            {
                task.data.arg.layoutType = 2;
            }
        }
        
        if(task.data.arg.layoutType == 2)
        {
            // 旧布局。
            return this.checkUpgradeOld(room,task)
        }
        else 
        {
            // 新布局
            return this.checkUpgradeNew(room,task)
        }
        
    }
    private static checkUpgradeOld(room:Room,task:ITask<ITeamTaskData<"upgrade">>):ETaskState
    {
        const teams = task.data.teams["TeamUpgrader"];
        if(!teams)
        {
            return ETaskState.Running;
        }
        
        for(const e of teams)
        {
            const targetroom = Game.rooms[task.data.room];

            const controllerentity =targetroom.controller!;
            const stores = controllerentity.getContainer();
            const core = targetroom.getEntity("CoreEntity");
           
            const level = controllerentity.level;
            if(level<8)
            {
                if(stores.length>0  )
                {
                    if(level>5)
                    {
                        if(!targetroom.canExecute(200))
                        {
                            // 没400T检测一次爬的数量
                            continue;
                        }
                    }
                    else 
                    {
                        if(!targetroom.canExecute(50))
                        {
                            continue;
                        }
                    }
                    
                   
                    const team = room.getEntityByID<TeamUpgrader>(e);
                    const max = team.maxWorker();
                    const upgraderRequird = team.getNodeMemory().required.find(e=>e[0].Role == "upgrader") as [IBodyConfig, number];
                    const creeps = team.getNodeMemory().creeps["upgrader"];
                    const works = _.sum(creeps,e=>Game.creeps[e].getActiveBodyparts(WORK));
                    targetroom.getNodeMemory().stats.upgradeWork =  works ;
                    
                    upgraderRequird[0].body=getRoleConfig("upgrader",room.controller?.level as number).body ;// 重新配置body的体型
                    if(room.getEntity("SpawnEntity").getTasksByOwner(e))
                    {
                        // 已经有孵化任务了不能再加了
                        continue;
                    }

                    if(team.getWorkProgress()> controllerentity.leftProgress()*1.1)
                    {
                        // 剩余的升级Work时间内已经可以升级了。
                        upgraderRequird[1]=BodyEfficiency.getCreepCount("upgrader",room.controller?.level as number,WORK,10);;
                        continue;
                    }
                    if(!core.Storage|| core.resourceCount(RESOURCE_ENERGY)>120000)
                    {
                        // 当当前所有的upgrader的效率能够使控制器升级时。则不再新增孵化
                        if(stores[0].store.getUsedCapacity(RESOURCE_ENERGY)> stores[0].store.getCapacity()*0.7)
                        {
                            // 当控制器的能量还很充足时。增加升级工的数量
                            
                            if(max> upgraderRequird[1])
                            {
                                upgraderRequird[1]++;
                            }
                        }
                        else if(stores[0].store.getUsedCapacity(RESOURCE_ENERGY)==0) 
                        {
                            if(  upgraderRequird[1]>1)
                            {
                                upgraderRequird[1]--;
                            }
                        }
                    }else 
                    {
                        upgraderRequird[1]=1;
                    }
                }
                else
                {
                    // 没有store则。此任务销毁
                    return ETaskState.Complete;
                }
            }
            else
            {
                // 到8了
                const team = room.getEntityByID<TeamUpgrader>(e);
                const upgraderRequird = team.getNodeMemory().required.find(e=>e[0].Role == "upgrader") as [IBodyConfig, number];
                upgraderRequird[1]=1;
                // return ETaskState.Complete; 这里应该要任务完成
            }
            

        }
        return ETaskState.Running;
    }

    private static checkDefend(room:Room,task:ITask<ITeamTaskData<"defend">>):ETaskState
    {
         return DefendTaskCheck.check(room,task);
    }

    private static checkDefendRam(room:Room,task:ITask<ITeamTaskData<"defendram">>):ETaskState
    {

        
        // 对敌方进行分组后。进行任务分配
        const workroom = Game.rooms[task.data.room]
        if(workroom)
        {
            if(workroom.controller?.safeMode && workroom.controller?.safeMode>1400)
            {
                return ETaskState.Complete
            }
            const cachehostiles = workroom.getWorld().PollHostiles(workroom.name);
            if(!cachehostiles)
            {
                return ETaskState.Running;
            }
            const enemy:Creep[] = [];
            const exist = new Set( cachehostiles.cacheData.map(e=>e.id).concat(task.data.arg.enemy));
            exist.forEach(e=>
                {
                    const obj = Game.getObjectById(e);
                    if(obj)
                    {
                        enemy.push(obj);
                    }
            })

            if(enemy.length==0)
            {
                return ETaskState.Complete
            }
            const defenders:Creep[]=[];
            const roles:Set<RoleName>= new Set<RoleName>(["defRed","defBlue"]);
            for(const e of task.data.creeps)
            {
                if(Game.creeps[e] && roles.has(Game.creeps[e].memory.Role ))
                {
                    defenders.push(Game.creeps[e]);
                }
            }
            // 同时对房间环境进行分析
            const groups = WarStrategy.classifyEnemy(enemy);

            this.setCreepTactic(defenders,groups as Creep[][]);

            task.data.arg.enemy = enemy.map(e=>e.id);
            if(task.data.arg.enemy .length== 0  )
            {
                const creepcount = _.sum (_.flatten(Object.values(task.data.teams)),e=>(room.getEntityByID(e) as ATeamEntity).creeps.length);
                if(creepcount ==0)
                {
                    room.log("info",`外矿防守任务 完成${JSON.stringify(task)}`);
                    return ETaskState.Complete
                }
            }
            
        }
        return ETaskState.Running;
    }
    private static setCreepTactic(alldefender:Creep[],grouparmys:Creep[][])
    {
        let min_group:Creep[]=grouparmys[0];
        let i=0;
        //const track:Record<string,Id<Creep>[]>={};
        
        const setDefendTactic=(defend:ICombat<IAttackTactic|IDefendTactic> ,enemy:Creep[])=>
        {
            defend.setTactic({
                type:1,
                enemy:enemy.map(e=>e.id)
            })
        }

        const setdefenderTask = (defender:Creep[],grouparmys:Creep[][])=>
        {
            // 如果敌方单位大于2则要分配两个
            let j=0;
            for(let i=0;i<grouparmys.length && j<defender.length;i++)
            {
                // const arratckids:Id<Creep>[]=_.map(grouparmys[i%grouparmys.length],e=> e.id);
                // 这里是防守
                 
                if(grouparmys[i].length>2)
                {
                    if( defender[j+1])
                    {
                        // defender[j+1].setTask(task);
                        //track[ defender[j+1].name]=arratckids
                        setDefendTactic(defender[j+1],grouparmys[i%grouparmys.length])
                    }

                    j+=2;
                }
                else
                {
                    setDefendTactic(defender[j],grouparmys[i%grouparmys.length])
                    // track[ defender[j].name]=arratckids
                    j++;
                }
                if(min_group.length>grouparmys[i].length)
                {
                    min_group=grouparmys[i];
                }
            }
            return j;
        }
        // const setDefender
        const usecount_red = setdefenderTask(alldefender,grouparmys);
        
        // 多余的红球或者是蓝球进行攻击
        for(let m=usecount_red;m<alldefender.length;m++)
        {
            setDefendTactic(alldefender[m],min_group);
            // track[ alldefender[m].name]=_.map(min_group,e=>e.id);
        }
        
    }
}